
namespace Patterns4Net.Attributes.DesignPatterns
{
    using System;

    /// <summary>
    /// Use this attribute to annotate a type as an implementation of the Composite design pattern.
    /// </summary>
    [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = true)]
    public sealed class CompositeAttribute : Attribute, IPatternAttribute
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="CompositeAttribute"/> class, 
        /// a value of the <see cref="Component"/> is inferred.
        /// </summary>
        public CompositeAttribute()
        {            
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="CompositeAttribute"/> class and 
        /// sets the <see cref="Component"/> property to provided value.
        /// </summary>
        public CompositeAttribute(Type component)
        {
            this.Component = component;
        }

        /// <summary>
        /// Gets or sets the type of the interface of Components that the Composite aggregates. 
        /// This is not required attribute. 
        /// </summary>
        /// <remarks>
        /// If it's value is not specified, Patterns4Net tries to infer it according to following rules:
        /// <list type="bullet">
        ///     <item><description>
        ///     If the Composite inherits from a class different then <see cref="object"/> this class is used
        ///     </description></item>
        ///     <item><description>
        ///     Otherwise first interfaces implemented by the Composite class.
        ///     </description></item>
        /// </list>
        /// </remarks>
        public Type Component { get; set; }
    }
}
